//
// Created by xkj on 2020/10/21.
//

#ifndef PROJ_ANDROID_CLASSPATHCHOOSE_H
#define PROJ_ANDROID_CLASSPATHCHOOSE_H

#include "cocos2d.h"
#include "extensions/cocos-ext.h"
#include "extensions/ExtensionExport.h"
#include "base/CCScheduler.h"

#include "base/CCDirector.h"
#include "renderer/CCRenderer.h"
#include "renderer/CCCustomCommand.h"
#include "network/CCDownloader.h"
#include "HandTianScene.h"
#include "SIOUserInfo.h"

#include "ActCmd.h"
#include "RemoteControlHelper.h"
#include "BlueToothHelper.h"

#include <stdlib.h>

USING_NS_CC;
USING_NS_CC_EXT;
using namespace cocos2d::network;
using namespace CocosDenshion;

#define CLASS_DATA_INFO_PATH "CLASS_PATH_CHOOSE.plist"
#define GAME_UUID_IN_NDK "GAME_UUID_IN_NDK.plist"
#define LOGIN_USER_INFO "LOGIN_USER_INFO.plist"

class ClassPathChoose: public cocos2d::Scene,public BlueToothHelperDelegate,public SocketIOHelperDelegate {
public:
    cocos2d::Label *displayLabel = nullptr;
    cocos2d::Label *connectBleLabel;
    LayerColor *pathLayer;
    Sprite *oneJoker;
    cocos2d::Size visibleSize;
    float topMarin;

    static cocos2d::Scene *createScene() {
        return ClassPathChoose::create();
    }

    virtual bool init() override {
        //////////////////////////////
        // 1. super init first
        if (!Scene::init()) {
            return false;
        }

        connectBleLabel = nullptr;
        visibleSize = Director::getInstance()->getVisibleSize();

        return true;
    }

    virtual void onEnterTransitionDidFinish() override {
        initBg();
        initTitle();
        initPromptLayer();
        initGlobal();

        initStorePageInfo();//        initPathLayer();
        initUserInfoFromLocal();
    }

    void initGlobal(){
        BlueToothHelper::notifyTarget = static_cast<BlueToothHelperDelegate *>(this);
        SocketIOHelper::delegate =  static_cast<SocketIOHelperDelegate *>(this);
        initKeyBoard();
    }

    void checkoutGlobal()
    {
        HttpClient::getInstance()->setClearRequestPredicate(nullptr);
        HttpClient::getInstance()->setClearResponsePredicate(nullptr);
        HttpClient::getInstance()->clearResponseAndRequestQueue();

        // actions
        this->stopAllActions();
        // timers
        this->unscheduleAllCallbacks();

        SocketIOHelper::delegate =  static_cast<SocketIOHelperDelegate *>(nullptr);
        BlueToothHelper::notifyTarget = static_cast<BlueToothHelperDelegate *>(nullptr);
    }

    void initUserInfoFromLocal() {
        std::string writablePath = FileUtils::getInstance()->getWritablePath();
        writablePath.append(LOGIN_USER_INFO);
        FileUtils::getInstance()->isFileExist(writablePath, [=](bool isExist) {
            if (isExist) {
                ValueMap userInfo = FileUtils::getInstance()->getValueMapFromFile(writablePath);
                loginUserInfo.roomId = userInfo["roomId"].asString()    ;
                loginUserInfo.signature  = userInfo["signature"].asString() ;
                loginUserInfo.avatar  = userInfo["avatar"].asString() ;
                loginUserInfo.gender  = userInfo["gender"].asString() ;
                loginUserInfo.roomId  = userInfo["role"].asString()   ;
                loginUserInfo.signature  = userInfo["signature"].asString() ;
                loginUserInfo.nickname  = userInfo["nickname"].asString()  ;

                if(loginUserInfo.signature.length() <= 0){
                    std::string writablePath = FileUtils::getInstance()->getWritablePath();
                    writablePath.append(LOGIN_USER_INFO);
                    FileUtils::getInstance()->removeFile(writablePath);

                    bool isFTM = JniHelper::callStaticBooleanMethod("org.cocos2dx.cpp.AppActivity", "isFromTongMeng");
                    if(isFTM){
                        auto scene = ClassPathChoose::createScene();
                        Director::getInstance()->replaceScene(scene);
                        BlueToothHelper::connectBleMacId = JniHelper::callStaticBooleanMethod("org.cocos2dx.cpp.AppActivity", "getGoodCopyDataToken");
                        return;
                    }

                    auto scene = HelloWorld::createScene();
                    Director::getInstance()->replaceScene(
                            TransitionFade::create(0.5, scene, Color3B(58, 81, 73)));

                    return;
                }

                if(loginUserInfo.avatar.length() > 5){
                    initSocketIO();
                }

                //=读头像============
                //========================
                std::string writablePath = FileUtils::getInstance()->getWritablePath();
                std::string userIconPath = writablePath+loginUserInfo.signature+".png";
                if(FileUtils::getInstance()->isFileExist(userIconPath)){
                    FileUtils::getInstance()->getDataFromFile(userIconPath, [=](const Data& readData) {
                        if(readData.getSize()>0) {
                            //setNotifyLabel(userIconPath);
                            initLoginUserIcon(readData.getBytes(), readData.getSize());
                        }else{
                            //setNotifyLabel("下载远程头像1");
                            downloadFriend(loginUserInfo.avatar, "登录用户头像");
                        }
                    });
                }else{
                    //setNotifyLabel("下载远程头像2");
                    downloadFriend(loginUserInfo.avatar, "登录用户头像");

                }

            }
        });
    }

//下载之友
    void downloadFriend(std::string url,std::string id)
    {
        //创建Request对象
        auto request = new HttpRequest();
        request->setUserData((void *)new std::string(id));
        //设置请求网址
        request->setUrl(url);
        //设置请求类型
        request->setRequestType(HttpRequest::Type::GET);
        //设置请求的数据
        //char data[50] = "data";
        //request->setRequestData(data,strlen(data));
        //完整的Request对象已经创建成功了

        request->setResponseCallback(CC_CALLBACK_2(ClassPathChoose::onHttpRequestCompleted, this));
        //创建HttpClient对象
        auto client = HttpClient::getInstance();//getInstance静态成员函数-单例模式模型
        client->setTimeoutForConnect(10);//当客户端向服务端发送请求超过这个时间，就会返回一个错误信息
        client->setTimeoutForRead(10);//接收数据的读取时间
        client->send(request);
        request->release();//释放请求
    }

    void onHttpRequestCompleted(HttpClient *sender, HttpResponse *response)
    {
        if (!response)
        {
            return;
        }

        HttpRequest* hRequest = response->getHttpRequest();
        std::string *id = static_cast<std::string*>(hRequest->getUserData());

        int statusCode = response->getResponseCode();
        if (statusCode != 200 ||
            !response->isSucceed()
                ){
            downFailed((*id), hRequest->getUrl());

            delete id;
            return;
        }


        downSuccess((*id), hRequest->getUrl(), (*response->getResponseData()));
        delete id;
    }
//下载失败の回调
    void downFailed(const std::string id,const std::string url)
    {
        //static_cast<Label *>(oneUserNode->getChildByName("running_title"))->setString(StringUtils::format("×任务：%s 错误:%s",id.c_str(),url.c_str()));
        downloadFriend(url, id);
    }
//下载成功の回调
    void downSuccess(const std::string &id,const  std::string &url, std::vector<char> &cnt)
    {
        if(id == "登录用户头像") {
            std::string writablePath = FileUtils::getInstance()->getWritablePath();
            std::string userIconPath = writablePath+loginUserInfo.signature+".png";
            Data writeData;
            writeData.copy((const unsigned char *)cnt.data(), cnt.size());
            initLoginUserIcon((const unsigned char *)cnt.data(), cnt.size());

            FileUtils::getInstance()->writeDataToFile(writeData, userIconPath, [=](bool success) {
                if (success)
                {
                }
                else
                {

                }
            });
        }
    }

    void writeInitPageInfo() {
        ValueMap pageInfo;
        pageInfo["curClass"] = Value(1);
        pageInfo["curTerm"] = Value(1);

        /*每年级有多少页面*/
        const static std::map<int, int> classPageMapping = {
                {12, 40},//6年级下半学期
                {11, 60},//6年级上半学期
                {10, 60},//5年级下半学期
                {9,  73},//5年级上半学期
                {8,  83},//4年级下半学期
                {7,  83},//4年级上半学期
                {6,  83},//3年级下半学期
                {5,  83},//3年级上半学期
                {4,  80},//2年级下半学期
                {3,  83},//2年级上半学期
                {2,  66},//1年级下半学期
                {1,  100} //1年级上半学期
        };

        int i=0;
        for (const auto &onePageStat:classPageMapping) {
            ValueMap ppageStat;

            int number = 0;

            ppageStat["totalPage"] = Value(onePageStat.second);
            ppageStat["curPage"] = Value(number);
            ppageStat["writtenPage"] = Value(number);


            pageInfo[std::to_string(onePageStat.first)] = Value(ppageStat);
        }

        std::string writablePath = FileUtils::getInstance()->getWritablePath();
        std::string fullPath = writablePath + CLASS_DATA_INFO_PATH;
        if (FileUtils::getInstance()->writeValueMapToFile(pageInfo, fullPath.c_str())) {
            setNotifyLabel("初始页码存储完毕√");
            handPageInfo = pageInfo;
        } else {
            setNotifyLabel("初始页码存储失败×");
        }
    }

    void runningJokerByPos(Vec2 myPos) {
        oneJoker->stopAllActions();
        oneJoker->setPosition(myPos);//左下角

        float timeCourse = 0.7f;
        auto oneJump = Spawn::create(
                MoveTo::create(timeCourse,
                               Vec2(myPos.x - 2, myPos.y)),
//                    ScaleTo::create(timeCourse, 1.1f, 1.1f),
                RotateTo::create(timeCourse, -5.0f),
                nullptr
        );

        auto oneCenter = Spawn::create(
                RotateTo::create(timeCourse, 5.0f),
//                                           ScaleTo::create(timeCourse, 1.05f, 1.05f),
                MoveTo::create(timeCourse / 2,
                               Vec2(myPos.x + 2, myPos.y)),
                nullptr
        );

        auto oneJumpBack = Spawn::create(
                MoveTo::create(timeCourse,
                               Vec2(myPos.x, myPos.y)),
//                    ScaleTo::create(timeCourse, 1.0f, 1.0f),
                RotateTo::create(timeCourse, 0.0f),
                nullptr
        );

        oneJoker->runAction(
                RepeatForever::create(
                        Sequence::create(
                                oneJump,
                                oneCenter,
                                oneJumpBack,
                                nullptr
                        )
                )
        );
    }

    void moveJokerToOpen() {
        //curPage = 1;
        //curTerm = 1;

        int pos = curPage * 2;
        if (curTerm == 1) {
            pos--;
        }
        pos--;

        runningJokerByPos(posThumb[pos]);
    }

    void bornJoker(int curClassNum, int curTermNum) {
        if (curClassNum > 6) {
            curClassNum = 6;
        }

        if (curTermNum > 2 ||
            curTermNum < 1
                ) {
            curTermNum = 2;
        }

        int pos = curPage * 2;
        if (curTerm == 1) {
            pos--;
        }
        pos--;

        oneJoker = Sprite::create("joker.png");
        oneJoker->setAnchorPoint(Vec2(0.7, 0.5));//左下角
        //oneJoker->setPosition(posThumb[pos]);//左下角
        oneJoker->setScale(38 / oneJoker->getContentSize().width);//左下角
        oneJoker->setOpacity(255 * 0.9);

        runningJokerByPos(posThumb[pos]);

        pathLayer->addChild(oneJoker);
    }

    void initStorePageInfo() {
        std::string writablePath = FileUtils::getInstance()->getWritablePath();
        writablePath.append(CLASS_DATA_INFO_PATH);
        FileUtils::getInstance()->isFileExist(writablePath, [=](bool isExist) {
            if (isExist) {
                handPageInfo = FileUtils::getInstance()->getValueMapFromFile(writablePath);
            } else {
                writeInitPageInfo();
            }

            curPage = handPageInfo["curClass"].asInt();
            curTerm = handPageInfo["curTerm"].asInt();

            initPathLayer();
            bornJoker(handPageInfo["curClass"].asInt(), handPageInfo["curTerm"].asInt());
            setOpenBook(handPageInfo["curClass"].asInt(), handPageInfo["curTerm"].asInt());
        });
    }

    void hideAllBookById(int i) {
        std::string fileNSuffix = fileNameThumb[i];
        std::string oneKOpen = "open_" + std::to_string(i);
        std::string oneCOpen = "close_" + std::to_string(i);
        std::string oneDOpen = "detail_" + std::to_string(i);

        pathLayer->getChildByName(oneKOpen)->setVisible(false);
        pathLayer->getChildByName(oneCOpen)->setVisible(false);
        pathLayer->getChildByName(oneDOpen)->setVisible(false);
    }

    void setOneBookByName(int bookIdx, const char *name) {
        std::string oneKey = name + std::to_string(bookIdx);

        Sprite *oneBook = static_cast<Sprite *>(pathLayer->getChildByName(oneKey));
        if (oneBook) {
            oneBook->setVisible(true);
        }

    }

    bool prevOpenBook() {
        setCloseBook(curPage, curTerm);
        if (curTerm == 2) {
            curTerm--;
        } else {
            curTerm = 2;
            curPage--;
        }

        if (curPage <= 0) {
            curPage = 1;
            curTerm = 1;

            setOpenBook(curPage, curTerm);

            return false;
        }

        setOpenBook(curPage, curTerm);
        return true;
    }

    bool nextOpenBook() {
        setCloseBook(curPage, curTerm);
        if (curTerm == 1) {
            curTerm++;
        } else {
            curTerm = 1;
            curPage++;
        }

        if (curPage > 6) {
            curPage = 6;
            curTerm = 2;

            setOpenBook(curPage, curTerm);

            return false;
        }

        setOpenBook(curPage, curTerm);
        return true;
    }

    void setCloseBook(int curClass, int curTerm) {
        int bookIdx = curClass * 2;
        if (curTerm == 1) {
            bookIdx--;
        }

        hideAllBookById(bookIdx - 1);
        std::string keyMap = std::to_string(bookIdx);
        ValueMap onePPageS = handPageInfo[keyMap].asValueMap();
        std::string oneKey;
        if (onePPageS["writtenPage"].asInt() == 0) {
            oneKey = "close_";
        } else {
            oneKey = "open_";
        }

        setOneBookByName(bookIdx - 1, oneKey.c_str());
    }

    void setOpenBook(int curClass, int curTerm) {
        int bookIdx = curClass * 2;
        if (curTerm == 1) {
            bookIdx--;
        }

        bookIdx--;
        hideAllBookById(bookIdx);
        setOneBookByName(bookIdx, "detail_");
    }

    void addAllBook(int i, std::string keyPrefix) {
        std::string fileNSuffix = keyPrefix + fileNameThumb[i];

        auto oneCT = Sprite::create(fileNSuffix);
        oneCT->setAnchorPoint(Vec2(0.5, 0));//左下角
        oneCT->setPosition(posThumb[i]);//左下角
        oneCT->setName(keyPrefix + std::to_string(i));
        oneCT->setOpacity(255 * 0.9);
        oneCT->setVisible(false);

        pathLayer->addChild(oneCT);
    }

    void addScoreBoard(int i,const char *name,ValueMap &onePPageS)
    {
        float wp = onePPageS["writtenPage"].asFloat();
        float tp = onePPageS["totalPage"].asFloat();
        float wPrecent = wp / tp;
        std::string oneKey = "open_";
        oneKey.append(std::to_string(i));

        auto oneBookS = pathLayer->getChildByName(oneKey);
        Vec2 oneBookV = oneBookS->getPosition();

        Rect oneOpenS = oneBookS->getBoundingBox();

        oneBookV.x -= (oneOpenS.size.width/2);
        oneBookV.y -= 10;

        std::string boardName = "score_";
        boardName.append(std::to_string(i));
        auto oneUserNode = Node::create();//LayerColor::create(Color4B(125,0,0,0), 100, 100);//Node::create();
        oneUserNode->setName(boardName);
        oneUserNode->setAnchorPoint(Vec2(0,0));
        oneUserNode->setName(boardName);
        oneUserNode->setPosition(oneBookV);
        pathLayer->addChild(oneUserNode);

        auto colorLayer = LayerColor::create(Color4B::WHITE, oneOpenS.size.width, 5);
        colorLayer->setAnchorPoint(Vec2(0,0));
        colorLayer->setPosition(Vec2(0,0));
        oneUserNode->addChild(colorLayer);

        //colorbar
        float colorBarWidth = oneOpenS.size.width*wPrecent;
        auto frontColorLayer = LayerColor::create(Color4B(0,150,244,255), colorBarWidth, 5);
        frontColorLayer->setAnchorPoint(Vec2(0,0));
        frontColorLayer->setPosition(Vec2(0,0));
        oneUserNode->addChild(frontColorLayer);
    }

    void initPathLayer() {
        float tianHeight = visibleSize.height - topMarin - 5;

        pathLayer = LayerColor::create(Color4B(125, 0, 0, 0), visibleSize.width * 0.7, tianHeight);
        pathLayer->setAnchorPoint(Vec2(0, 0));//左下角
        pathLayer->setPosition(Vec2(visibleSize.width * 0.15, 0));

        pathLayer->setName("path_layer");

        this->addChild(pathLayer);

        //=================
        //handPageInfo
        for (int i = 0; i < fileNameThumb.size(); i++) {
            std::string fileNSuffix = fileNameThumb[i];
            std::string keyMap = std::to_string(i + 1);
            ValueMap onePPageS = handPageInfo[keyMap].asValueMap();

            addAllBook(i, "open_");
            addAllBook(i, "close_");

            std::string oneKey;
            if (onePPageS["writtenPage"].asInt() == 0) {
                oneKey = "close_";
            } else {
                oneKey = "open_";
            }

            if(onePPageS["writtenPage"].asInt() > 0) {
                addScoreBoard(i,"score_", onePPageS);
            }

            oneKey.append(std::to_string(i));
            pathLayer->getChildByName(oneKey)->setVisible(true);
        }

        for (int i = 0; i < fileNameThumb.size(); i++) {
            addAllBook(i, "detail_");
        }
            //----------------------
    }

    void flashLogoutSelect()
    {
        //nodeSelectGrid->runAction(Lens3D::create(0.3, logoutSelectS->getContentSize(), logoutSelectS->getPosition(), logoutSelectS->getContentSize().width));
        logoutSelectS->runAction(Sequence::create(ScaleTo::create(0.2f, logoutSelectScale*0.9),ScaleTo::create(0.1f, logoutSelectScale), nullptr));
    }

    void chooseExitConfirm()
    {
        flashLogoutSelect();
        showComfirmLayer();
        logoutUnselecting();
    }

    void changeExitConfirm()
    {
        Sprite *ceS       = static_cast<Sprite *>(this->getChildByName("confirm_layer")->getChildByName("confirm_exit"));
        Sprite *ceScancle = static_cast<Sprite *>(this->getChildByName("confirm_layer")->getChildByName("confirm_cancel"));

        if(isLogoutConfirm){
            ceS->setVisible(false);
            ceScancle->setVisible(true);
            isLogoutConfirm = false;
        }else{
            ceS->setVisible(true);
            ceScancle->setVisible(false);
            isLogoutConfirm = true;
        }
    }

    void showComfirmLayer()
    {
        isMenuSelect = false;
        logoutTimeout = 0;

        auto mastLayer = LayerColor::create(Color4B(88,87,86, 120), visibleSize.width, visibleSize.height);
        mastLayer->setAnchorPoint(Vec2(0, 0));//左下角
        mastLayer->setPosition(Vec2(0, 0));

        mastLayer->setName("confirm_layer");

        auto ceS = Sprite::create("confirm_exit.png");
        ceS->setAnchorPoint(Vec2(0.5, 0.5));
        ceS->setVisible(false);
        ceS->setName("confirm_exit");
        ceS->setPosition(Vec2(visibleSize.width*0.5, visibleSize.height*0.64));
        mastLayer->addChild(ceS);


        auto ceScancle = Sprite::create("confirm_cancel.png");
        ceScancle->setVisible(true);
        ceScancle->setName("confirm_cancel");
        ceScancle->setAnchorPoint(Vec2(0.5, 0.5));
        ceScancle->setPosition(Vec2(visibleSize.width*0.5, visibleSize.height*0.64));
        mastLayer->addChild(ceScancle);

        this->addChild(mastLayer);

        isLogoutConfirm = false;
    }

    void initKeyBoard() {
        auto listener = EventListenerKeyboard::create();
        listener->onKeyPressed = [=](EventKeyboard::KeyCode keyCode, Event *event) {
            ControlCode pressKey = ControlCode(keyCode);
            setKeyAct(pressKey);
        };

        listener->onKeyReleased = [=](EventKeyboard::KeyCode keyCode, Event *event) {
        };

        _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
    }

    void initBg() {
        auto visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();

        //贴图的纹理图片宽高必须是2的n次幂，128x128
        auto bg = Sprite::create(
                "background2.jpg");//, Rect(0, 0, visibleSize.width, visibleSize.height));
        Size mysize = bg->getContentSize();
        bg->setScaleX(visibleSize.width / mysize.width);
        bg->setScaleY(visibleSize.height / mysize.height);

        //贴图的纹理参数，水平重复平铺，垂直重复平铺
        /*
        Texture2D::TexParams tp = {                backend::SamplerFilter::LINEAR,
                                                   backend::SamplerFilter::LINEAR,
                                                   backend::SamplerAddressMode::REPEAT,
                                                   backend::SamplerAddressMode::REPEAT
        };

        //bg->getTexture()->setTexParameters(tp);
         */
        bg->setAnchorPoint(Vec2::ZERO);
        bg->setPosition(0, 0);//origin + Vec2(visibleSize.width/2, visibleSize.height/2));
        this->addChild(bg, -1);

    }

    void initLoginUserIcon(const unsigned char *data, ssize_t dataLen)
    {
        auto visibleSize = Director::getInstance()->getVisibleSize();
        float layerHeight = visibleSize.height*0.06;
        auto colorLayer = LayerColor::create(Color4B(29, 29, 29, 0), visibleSize.width*0.26,layerHeight);//Node::create();//
        colorLayer->setName("login_info_area");
        colorLayer->setAnchorPoint(Vec2(0,1));
        colorLayer->setPosition(Vec2(visibleSize.width*0.73,visibleSize.height*0.93));
        this->addChild(colorLayer);

        //--用户头像--------------------------
        auto mask = Sprite::create("avator_mask.png");
        mask->setAnchorPoint(Vec2(0, 0));
        mask->setScale(layerHeight/mask->getContentSize().height);

        do {
            Texture2D* texture = nullptr;
            Image imgimg;
            if (false == imgimg.initWithImageData((const unsigned char *) data, dataLen)) {
                break;
            }

            texture = new Texture2D();
            if (false == texture->initWithImage(&imgimg)) {
                break; 
            }

            auto img = Sprite::createWithTexture(texture);
//将头像大小缩放为模板大小
            img->setScale(layerHeight / img->getContentSize().height);
            img->setAnchorPoint(Vec2(0, 0));

            auto clipNode = ClippingNode::create();
            clipNode->setAlphaThreshold(0.0f);
            clipNode->setStencil(mask);
            clipNode->addChild(img);
            clipNode->setAnchorPoint(Vec2(1, 1));
            clipNode->setPosition(Vec2(0, 0));

            colorLayer->addChild(clipNode);
        }while(0);

        auto circle = Sprite::create("avator_mask_frame.png");
        circle->setAnchorPoint(Vec2(0, 0));
        circle->setScale(layerHeight/circle->getContentSize().height);
        circle->setPosition(Vec2(0, 0));
        colorLayer->addChild(circle);

        //=================
        auto nameLabel = Label::createWithTTF(loginUserInfo.nickname, "fonts/content.ttf", 34);
        nameLabel->setAnchorPoint(Vec2(0, 0.5));
        nameLabel->setTextColor(Color4B(20,0,28,255));// 13,12,12  0,43,40  0,34,40 25,24,22    43,8,7
        //connectBleLabel->setHeight(connectBleLabel->getContentSize().height);
        float disLabX = layerHeight+20;
        float disLabY = layerHeight/2;
        nameLabel->setPosition(Vec2(disLabX, disLabY));//visibleSize.width*0.64, 0
        colorLayer->addChild(nameLabel);

        //========================
        float disLabX1 = nameLabel->getPosition().x+nameLabel->getContentSize().width+20;
        float disLabY1 = layerHeight/2;

        auto wifiO = Sprite::create("wifi_open.png");
        wifiO->setAnchorPoint(Vec2(0, 0.5));
        wifiO->setScale(layerHeight*0.5/wifiO->getContentSize().height);
        wifiO->setPosition(Vec2(disLabX1, disLabY1));
        colorLayer->addChild(wifiO);


        //= wifi_open.png =======================
        float disLabX2 = wifiO->getPosition().x+wifiO->getContentSize().width+20;
        float disLabY2 = layerHeight/2;

        auto bluetho = Sprite::create("bluetooth_open.png");
        bluetho->setAnchorPoint(Vec2(0, 0.5));
        bluetho->setScale(layerHeight*0.5/bluetho->getContentSize().height);
        bluetho->setPosition(Vec2(disLabX2, disLabY2));
        colorLayer->addChild(bluetho);

        //= logout_unselect.png =======================
        float disLabX3 = bluetho->getPosition().x+bluetho->getContentSize().width;
        float disLabY3 = layerHeight/2;

        logoutUnselectS = Sprite::create("logout_unselect.png");
        logoutUnselectS->setAnchorPoint(Vec2(0, 0.5));
        logoutUnselectS->setScale(layerHeight/logoutUnselectS->getContentSize().height);
        logoutUnselectS->setPosition(Vec2(disLabX3, disLabY3));
        logoutUnselectS->setVisible(true);

        //colorLayer->addChild(nodeUnselectGrid);
        colorLayer->addChild(logoutUnselectS);

        logoutSelectS = Sprite::create("logout_select.png");
        logoutSelectScale = (layerHeight*1.2)/logoutSelectS->getContentSize().height;

        //logoutSelectS->setAnchorPoint(Vec2(0, 0.5));
        logoutSelectS->setAnchorPoint(Vec2(0, 0.5));
        logoutSelectS->setScale(logoutSelectScale);
        //logoutSelectS->setPosition(Vec2(disLabX3, disLabY3));
        logoutSelectS->setPosition(Vec2(0, 0));
        logoutSelectS->setVisible(false);

        nodeSelectGrid = NodeGrid::create();
        nodeSelectGrid->setAnchorPoint(Vec2(0, 0.5));
        nodeSelectGrid->setPosition(Vec2(disLabX3, disLabY3));
        nodeSelectGrid->addChild(logoutSelectS);

        colorLayer->addChild(nodeSelectGrid);
        //colorLayer->addChild(logoutSelectS);

        isMenuSelect = false;
        logoutTimeout = 0;
    }

    void logoutSelecting(){
        logoutUnselectS->setVisible(false);
        logoutSelectS->setVisible(true);
        isMenuSelect = true;

        pathLayer->runAction(ScaleTo::create(0.2f, 0.9f));

        logoutTimeoutUnselect();
    }

    void logoutTimeoutUnselect(){
        this->scheduleOnce([=](float dt) {
            if(!isMenuSelect){
                return;
            }

            if(logoutTimeout > 0){
                logoutTimeoutUnselect();
            }else{
                logoutUnselecting();
            }
        },logoutTimeout ,"logoutTimeout");
        logoutTimeout = 0;
    }

    void logoutUnselecting(){
        logoutUnselectS->setVisible(true);
        logoutSelectS->setVisible(false);
        isMenuSelect = false;

        pathLayer->runAction(ScaleTo::create(0.2f, 1.0f));
    }


    //放下一个命令
    virtual void setOneAct(ActCmd &oneCmd) override {
        if (oneCmd.act == Pen_Write) {
            if (oneCmd.actDetail == PenStatus_Down) {
            }

            if (oneCmd.actDetail == PenStatus_Move) {
            }

            if (oneCmd.actDetail == PenStatus_Up) {
            }

            if (oneCmd.actDetail == PenStatus_Leave) {
            }

            if (oneCmd.actDetail == PenStatus_Hover) {
            }
        }

        if (oneCmd.act == Pen_Ctl) {
            if (oneCmd.actDetail == PenStatus_SAVE) {
            }
            if (oneCmd.actDetail == PenStatus_CLEAR) {
            }
            if (oneCmd.actDetail == PenStatus_BLUE) {
            }
            if (oneCmd.actDetail == PenStatus_BLACK) {
            }
            if (oneCmd.actDetail == PenStatus_RED) {
            }
            if (oneCmd.actDetail == PenStatus_PEN_FINE) {
            }
            if (oneCmd.actDetail == PenStatus_PEN_MEDIUM) {
            }
            if (oneCmd.actDetail == PenStatus_PEN_BOLD) {
            }
            if (oneCmd.actDetail == PenStatus_MOUSE_CHOOSE) {
            }
            if (oneCmd.actDetail == PenStatus_PEN_CHOOSE) {
            }
            if (oneCmd.actDetail == PenStatus_NEXT) {
            }
            if (oneCmd.actDetail == PenStatus_PREV) {
            }
        }

    }

    void initTitle() {
        Vec2 origin = Director::getInstance()->getVisibleOrigin();

        /////////////////////////////
        // 2. add a menu item with "X" image, which is clicked to quit the program
        //    you may modify it.

        // add a "close" icon to exit the progress. it's an autorelease object
        auto closeItem = MenuItemImage::create(
                "backNormal.png",
                "backSelected.png",
                CC_CALLBACK_1(ClassPathChoose::menuCloseCallback, this));

        if (closeItem == nullptr ||
            closeItem->getContentSize().width <= 0 ||
            closeItem->getContentSize().height <= 0) {
            Director::getInstance()->popScene();
        } else {
            float x = origin.x + visibleSize.width - closeItem->getContentSize().width / 2;
            float y = origin.y + closeItem->getContentSize().height / 2;
            closeItem->setPosition(Vec2(x, y));
        }

        // create menu, it's an autorelease object
        auto menu = Menu::create(closeItem, NULL);
        menu->setPosition(Vec2::ZERO);
        this->addChild(menu);

        /////////////////////////////
        // 3. add your codes below...
        //智慧好字帖
        auto item4 = MenuItemFont::create("", [&](Ref *sender) {
        });

        item4->setFontSizeObj(64);
        item4->setFontName("fonts/content.ttf");
        item4->setName("bandTitle");

        float menuTx = origin.x + visibleSize.width / 2;// - closeItem->getContentSize().width/2;
        float menuTyA = origin.y + visibleSize.height / 2;//-(item4->getContentSize().height/2);
        float menuTyB = origin.y + visibleSize.height - (item4->getContentSize().height / 2);

        //选择年级
        displayLabel = Label::createWithTTF("", "fonts/content.ttf", 32);
        auto pMenu = MenuItemLabel::create(displayLabel, [&](Ref *sender) {});
        pMenu->setAnchorPoint(Vec2(0, 1));
        pMenu->setPosition(Vec2(0, 0));

        // add the label as a child to this layer
        //this->addChild(displayLabel, 2);
        auto menuTop = Menu::create(item4, pMenu, nullptr);
        menuTop->alignItemsHorizontally();
        menuTop->setPosition(Vec2(menuTx, menuTyB));//menuTyA
        menuTop->setName("menuTop");

        this->addChild(menuTop);

        menuTop->runAction(
                EaseIn::create(MoveTo::create(0.7, Vec2(menuTx, menuTyB)), 1)
        );

        topMarin = item4->getContentSize().height + (visibleSize.height * 0.02);
    }

    void menuCloseCallback(cocos2d::Ref *pSender) {
        checkoutGlobal();
        auto scene = HelloWorld::createScene();
        Director::getInstance()->replaceScene(
                TransitionFade::create(2.5, scene, Color3B(58, 81, 73)));
    }

    virtual void setNotifyLabel(std::string cnt) override {
        if (displayLabel != nullptr) {
            displayLabel->setString(cnt);
        }
    }


    void setKeyAct(ControlCode &pressKey) override {
        if (pressKey == KEY_MENU) {
        }

        //如果按返回就退出
        if (pressKey == KEY_RETURN ||
            pressKey == KEY_TV_RETURN
        ) {
            BlueToothHelper::notifyTarget->setNotifyLabel("ヾ(￣▽￣)Bye~Bye~");
            Director::getInstance()->end();
            exit(EXIT_SUCCESS);
            /*
            Director::getInstance()->getScheduler()->performFunctionInCocosThread([=]() {

                if(this->getChildByName("confirm_layer") != nullptr) {
                    this->getChildByName("confirm_layer")->removeFromParent();
                }else {
                        chooseExitConfirm();
    / *
                        BlueToothHelper::notifyTarget->setNotifyLabel("ヾ(￣▽￣)Bye~Bye~");
                        //Director::getInstance()->end()
                        checkoutGlobal();
                        auto scene = HelloWorld::createScene();
                        Director::getInstance()->replaceScene(
                                TransitionFade::create(2.5, scene, Color3B(58, 81, 73)));
    * /
                }
            });
    */
        }

        if (pressKey == VOLUMN_UP ||
            pressKey == VOLUMN_DOWN
                ) {

            if (pressKey == VOLUMN_UP) {
                Director::getInstance()->getScheduler()->performFunctionInCocosThread([=]() {
                    showPromptLayer();
                });
            }

            if (pressKey == VOLUMN_DOWN) {

                Director::getInstance()->getScheduler()->performFunctionInCocosThread([=]() {
                    hidePromptLayer();
                });
            }

        }

        if (pressKey == PROGRAM_UP ||
            pressKey == PROGRAM_DONW
                ) {
            if (pressKey == PROGRAM_UP) {

            }

            if (pressKey == PROGRAM_DONW) {

            }
        }

        if (pressKey == VOLUMN_MUTE) {
            Director::getInstance()->getScheduler()->performFunctionInCocosThread([=]() {

            });

        }

        if (pressKey == KEY_UP) {
            if(this->getChildByName("confirm_layer") != nullptr){
                changeExitConfirm();
                return;
            }

            logoutTimeout=3;
            if(isMenuSelect){
                flashLogoutSelect();

                return;
            }

            logoutSelecting();

        }

        if (pressKey == KEY_DOWN) {
            if(this->getChildByName("confirm_layer") != nullptr){
                changeExitConfirm();
                return;
            }

            if(!isMenuSelect){
                return;
            }

            logoutUnselecting();
        }

        if (pressKey == KEY_LEFT) {
            if(this->getChildByName("confirm_layer") != nullptr){
                changeExitConfirm();
                return;
            }

            logoutTimeout = 3;
            if(isMenuSelect){
                flashLogoutSelect();

                return;
            }

            if (prevOpenBook()) {
                moveJokerToOpen();
            }
        }

        if (pressKey == KEY_RIGHT) {
            if(this->getChildByName("confirm_layer") != nullptr){
                changeExitConfirm();
                return;
            }

            logoutTimeout = 3;
            if(isMenuSelect){
                flashLogoutSelect();

                return;
            }

            if (nextOpenBook()) {
                moveJokerToOpen();
            }
        }

        if (pressKey == KEY_CHOOSE) {
            if(this->getChildByName("confirm_layer") != nullptr){
                if(isLogoutConfirm){
                    removeLoginInfoFile();
                }else{
                    this->getChildByName("confirm_layer")->removeFromParent();
                }
                return;
            }

            if(isMenuSelect){
                chooseExitConfirm();
                return;
            }

            storePageInfo();

            HandTianScene::classNum = curPage;
            HandTianScene::termNo = curTerm;

            int pos = curPage * 2;
            if (curTerm == 1) {
                pos--;
            }

            ValueMap hpiMap = handPageInfo[std::to_string(pos)].asValueMap();
            HandTianScene::pageNo = hpiMap["curPage"].asInt();
            if(HandTianScene::pageNo <= 0){
                HandTianScene::pageNo = 1;
            }

            checkoutGlobal();
            auto scene = HandTianScene::createScene();
            Director::getInstance()->replaceScene(TransitionFade::create(1.5, scene, Color3B(58,81,73)));

            oneJoker->stopAllActions();
            oneJoker->runAction(ScaleTo::create(1.5, 0.5));
        }
    }

    void removeLoginInfoFile()
    {
        std::string writablePath = FileUtils::getInstance()->getWritablePath();
        writablePath.append(LOGIN_USER_INFO);
        if (FileUtils::getInstance()->removeFile(writablePath))
        {

        }
        else
        {

        }

        setNotifyLabel("ヾ(￣▽￣)Bye~Bye~");
        checkoutGlobal();
        auto scene = HelloWorld::createScene();
        Director::getInstance()->replaceScene(TransitionFade::create(1.5, scene, Color3B(58,81,73)));

    }

    void storePageInfo()
    {
        handPageInfo["curClass"] = Value(curPage);
        handPageInfo["curTerm"] = Value(curTerm);

        std::string writablePath = FileUtils::getInstance()->getWritablePath();
        std::string fullPath = writablePath + CLASS_DATA_INFO_PATH;
        if (FileUtils::getInstance()->writeValueMapToFile(handPageInfo, fullPath.c_str())) {
            //setNotifyLabel("初始页码存储完毕√");
        } else {
            setNotifyLabel("初始页码存储失败×");
        }
    }

    void setDebugLabel(std::string cnt) {
        if (connectBleLabel != nullptr) {
            auto newCnt = StringUtils::format("%s\n%s", cnt.c_str(),
                                              connectBleLabel->getString().c_str());

            connectBleLabel->setString(newCnt);
            float disLabY = Director::getInstance()->getVisibleSize().height -
                            connectBleLabel->getContentSize().height;
            connectBleLabel->setPosition(Vec2(20, disLabY));//visibleSize.width*0.64, 0
        }
    }

    void initPromptLayer() {
        auto visibleSize = Director::getInstance()->getVisibleSize();

        auto promptLayer = LayerColor::create(Color4B(29, 29, 29, 125), visibleSize.width,
                                              visibleSize.height);
        promptLayer->setAnchorPoint(Vec2(0, 0));
        promptLayer->setPosition(Vec2(visibleSize.width, 0));//));//visibleSize.width*0.70
        promptLayer->setName("promptLayer");

        connectBleLabel = Label::createWithTTF("debug info:", "fonts/content.ttf", 24);
        connectBleLabel->setAnchorPoint(Vec2(0, 0));
        //connectBleLabel->setHeight(connectBleLabel->getContentSize().height);
        float disLabX = visibleSize.width * 0.30 / 2;
        float disLabY = visibleSize.height - connectBleLabel->getContentSize().height;
        connectBleLabel->setPosition(Vec2(20, disLabY));//visibleSize.width*0.64, 0
        promptLayer->addChild(connectBleLabel, 3);

        this->addChild(promptLayer);
        //auto moveTo = MoveTo::create(1, Vec2(visibleSize.width*0.7, 0));
        //promptLayer->runAction(moveTo);
    }

    void showPromptLayer() {
        Vec2 promptLayPos = connectBleLabel->getParent()->getPosition();
        //if(promptLayPos.x == visibleSize.width){
        connectBleLabel->getParent()->stopAllActions();
        connectBleLabel->getParent()->runAction(
                MoveTo::create(1, Vec2(visibleSize.width * 0.75, 0))
        );
        //}
    }

    void hidePromptLayer() {
        Vec2 promptLayPos = connectBleLabel->getParent()->getPosition();
        //if(promptLayPos.x < visibleSize.width){
        connectBleLabel->getParent()->stopAllActions();
        connectBleLabel->getParent()->runAction(
                EaseBounceOut::create(MoveTo::create(0.5, Vec2(visibleSize.width, 0)))
        );
        //}
    }

    void SioJoinRoom(){
        std::string channelName = loginInInfo["login_sign"].asString();
        SocketIOHelper::getInstant()->emit("store-roomid", channelName);

        channelName.append("\r\nND_LOGIN\r\navatorloginOTT\r\n智慧好字帖\r\n1\r\nsignatureloginOTT\r\n ");
        SocketIOHelper::getInstant()->emit("join-room", channelName);
    };

    void initStoreUUIDAndRegister() {
        std::string writablePath = FileUtils::getInstance()->getWritablePath();
        writablePath.append(GAME_UUID_IN_NDK);
        FileUtils::getInstance()->isFileExist(writablePath, [=](bool isExist) {
            if (isExist) {
                loginInInfo = FileUtils::getInstance()->getValueMapFromFile(writablePath);
            }
        });
    }
    void SioConnection(SIOClient *client, const std::string&data) override
    {
        initStoreUUIDAndRegister();
        //setNotifyLabel("初始页码存储完毕√");
    }
    void SioOnline(SIOClient *client, const std::string&data) override{
    }
    void SioStatInfo(SIOClient *client, const std::string&data) override{
        //BlueToothHelper::notifyTarget->setNotifyLabel("SioStatInfo");
    }
    void SioStoreRoomid(SIOClient *client, const std::string &md5) override
    {
    }
    void SioShareCode(SIOClient *client, const std::string& url) override{

    }
    void SioOffline(SIOClient *client, const std::string&data) override{

    }
    void SioTalking(SIOClient *client,const std::string &data) override{

    }
    void SioRoomCommentator(SIOClient *client, const std::string&data) override{

    }
    void SioOnConnect(SIOClient* client) override{

    }
    void SioOnMessage(SIOClient* client, const std::string& data) override{

    }
    void SioOnError(cocos2d::network::SIOClient* client, const std::string&data ) override{

    }

    void SioOnClose(cocos2d::network::SIOClient* client) override{
        initSocketIO();
    }
    void SioRoomVisitors(SIOClient *client, const std::string& data) override{

    }
    void initSocketIO(){
        this->scheduleOnce([=](float dt) {
            SocketIOHelper::checkConnection();
        },1.0f ,"initSocketIO");
    };
    CREATE_FUNC(ClassPathChoose);

private:

    //书の图汉位置
    std::array<std::string, 12> fileNameThumb = {"class_1_1_thumb.png", "class_1_2_thumb.png",
                                                 "class_2_1_thumb.png", "class_2_2_thumb.png",
                                                 "class_3_1_thumb.png", "class_3_2_thumb.png",
                                                 "class_4_1_thumb.png", "class_4_2_thumb.png",
                                                 "class_5_1_thumb.png", "class_5_2_thumb.png",
                                                 "class_6_1_thumb.png", "class_6_2_thumb.png"};
    std::array<Vec2, 12> posThumb = {Vec2(411, 624), Vec2(124, 461), Vec2(106, 274), Vec2(546, 246),
                                     Vec2(590, 431), Vec2(673, 571), Vec2(940, 562),
                                     Vec2(1133, 652), Vec2(1280, 571), Vec2(954, 401),
                                     Vec2(867, 274), Vec2(1255, 349)};

    ValueMap handPageInfo;
    ValueMap loginInInfo;

    int curPage;
    int curTerm;

    SIOUserInfo loginUserInfo;
    Sprite *logoutSelectS;
    Sprite *logoutUnselectS;
    bool isMenuSelect;
    NodeGrid *nodeSelectGrid;
    float logoutSelectScale;
    int logoutTimeout;
    bool isLogoutConfirm;
};
#endif //PROJ_ANDROID_CLASSPATHCHOOSE_H                                                                                                                                                                                            